package com.esteel.settlement.pa.packet;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.Length;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.util.Assert;

/**
 * 业务报文头
 * 
 * @author zhangxiuzhi
 *
 */
public class BusinessHeader implements Serializable {

	// 业务报文头长度
	public static int HEADERLEN = 122;

	public static SimpleDateFormat SFDate = new SimpleDateFormat("yyyyMMdd");
	public static SimpleDateFormat SFTime = new SimpleDateFormat("HHmmss");
	public static SimpleDateFormat SFALLDate = new SimpleDateFormat("yyyyMMddHHmmss");

	Charset charset = Charset.forName("GBK");
	
	// 1 交易类型
	@Length(max = 4)
	@NotNull
	private String tranFunc;

	// 2 服务类型
	@Length(max = 2)
	@NotNull
	private String servType;

	// 3 MAC码
	@Length(max = 16)
	@NotNull
	private String macCode;

	// 交易日期
	@NotNull
	private Date tranDate;
	// //4 交易日期
	// @Length(max=8,min=8)
	// private String tranDate;
	//
	//
	// //5 交易时间
	// @Length(max=6,min=6)
	// private String tranTime;

	// 6 应答码
	@Length(max = 6, min = 6)
	@NotNull
	private String rspCode = "999999";

	// 7 应答码描述
	@Length(max = 42)
	@NotNull
	private String rspMsg;

	// 8 后续包标志

	@Max(1)
	@Min(0)
	@NotNull
	private int conFla = 0;

	// 9 报文体长度
	@NotNull
	private int length;

	// 10 操作员号
	@NotNull
	@Length(max = 5)
	private String counterId;

	// 11 请求方系统流水号
	@NotNull
	@Length(max = 20)
	private String thirdLogNo;

	// 12 交易网代码
	@NotNull
	@Length(max = 4)
	private String qydm;

	public String getTranFunc() {
		return tranFunc;
	}

	public void setTranFunc(String tranFunc) {
		this.tranFunc = tranFunc;
	}

	public String getServType() {
		return servType;
	}

	public void setServType(String servType) {
		this.servType = servType;
	}

	public String getMacCode() {
		return macCode;
	}

	public void setMacCode(String macCode) {
		this.macCode = macCode;
	}

	public String getRspCode() {
		return rspCode;
	}

	public void setRspCode(String rspCode) {
		this.rspCode = rspCode;
	}

	public String getRspMsg() {
		return rspMsg;
	}

	public void setRspMsg(String rspMsg) {
		this.rspMsg = rspMsg;
	}

	public Date getTranDate() {
		return tranDate;
	}

	public void setTranDate(Date tranDate) {
		this.tranDate = tranDate;
	}

	public int getConFla() {
		return conFla;
	}

	public void setConFla(int conFla) {
		this.conFla = conFla;
	}

	public int getLength() {
		return length;
	}

	public void setLength(int length) {
		this.length = length;
	}

	public String getCounterId() {
		return counterId;
	}

	public void setCounterId(String counterId) {
		this.counterId = counterId;
	}

	public String getThirdLogNo() {
		return thirdLogNo;
	}

	public void setThirdLogNo(String thirdLogNo) {
		this.thirdLogNo = thirdLogNo;
	}

	public String getQydm() {
		return qydm;
	}

	public void setQydm(String qydm) {
		this.qydm = qydm;
	}

	public byte[] getBusinessHeader() {
		int dstBegin = 0;
		byte[] dst = new byte[122];

		for (int i = 0; i < dst.length; i++) {
			dst[i] = ' ';
		}

		// 1 交易类型
		if (tranFunc != null){
			byte[] src = tranFunc.getBytes(charset);
			System.arraycopy(src, 0, dst, dstBegin, 4);
		}
		dstBegin += 4;
		// 2 服务类型
		if (servType != null){
			byte[] src = servType.getBytes(charset);
			System.arraycopy(src, 0, dst, dstBegin, 2);			
		}
		dstBegin += 2;
		// 3 MAC码
		if (macCode != null){
			byte[] src = servType.getBytes(charset);
			System.arraycopy(src, 0, dst, dstBegin, src.length>16?16:src.length);			
		}
		dstBegin += 16;
		// 10 交易日期
		if (getTranDate() != null){
			byte[] src = SFDate.format(this.getTranDate()).getBytes(charset);
			System.arraycopy(src, 0, dst, dstBegin, 8);
			
			// 11 交易时间
			
			src = SFTime.format(this.getTranDate()).getBytes(charset);
			System.arraycopy(src, 0, dst, dstBegin+8, 6);		
		}


		dstBegin += 8;
		dstBegin += 6;
		// 6 应答码
		if (rspCode != null){
			byte[] src = rspCode.getBytes(charset);
			System.arraycopy(src, 0, dst, dstBegin, src.length>6?6:src.length);		
		}
		dstBegin += 6;
		// 7 应答码描述
		if (rspMsg != null){
			byte[] src = rspMsg.getBytes(charset);
			System.arraycopy(src, 0, dst, dstBegin, src.length>42?42:src.length);	
		}
		dstBegin += 42;
		// 8 后续包标志
		
		byte[] src = new Integer(conFla).toString().getBytes(charset);
		System.arraycopy(src, 0, dst, dstBegin, 1);	
		dstBegin += 1;

		// 9 报文体长度
		String lengthStr = Integer.toString(this.length);
		for (int i = lengthStr.length(); i < 8; i++) {
			lengthStr = "0"+lengthStr;
		}
		src = lengthStr.getBytes(charset);
		System.arraycopy(src, 0, dst, dstBegin, 8);	
		dstBegin += 8;
		
		// 10 操作员号
		if (counterId != null){
			src = counterId.getBytes(charset);
			System.arraycopy(src, 0, dst, dstBegin, src.length>5?5:src.length);	
		}
		dstBegin += 5;
		// 11 请求方系统流水号
		src = thirdLogNo.getBytes(charset);
		System.arraycopy(src, 0, dst, dstBegin, src.length>20?20:src.length);	
		dstBegin += 20;
		// 12 交易网代码
		if (qydm != null){
			src = qydm.getBytes(charset);
			System.arraycopy(src, 0, dst, dstBegin, src.length>4?4:src.length);	
		}


		return dst;
	}

	/**
	 * 解析报文头信息
	 * 
	 * @param header
	 *            报文
	 */
	public void analyze(byte[] src) {
		Assert.isTrue(src.length >= BusinessHeader.HEADERLEN, "报文头长度必须大于" + BusinessHeader.HEADERLEN);
		int srcPos = 0;
		// 1 交易类型
		byte[] dest = new byte[4];
		System.arraycopy(src, srcPos, dest, 0, dest.length);
		this.setTranFunc(new String(dest).trim());
		srcPos += 4;
		// 2 服务类型
		dest = new byte[2];
		System.arraycopy(src, srcPos, dest, 0, dest.length);
		this.setServType(new String(dest).trim());
		srcPos += 2;
		// 3 MAC码
		dest = new byte[16];
		System.arraycopy(src, srcPos, dest, 0, dest.length);
		this.setMacCode(new String(dest).trim());
		srcPos += 16;
		// 4 交易日期
		// 5 交易时间
		dest = new byte[14];
		System.arraycopy(src, srcPos, dest, 0, dest.length);
		try {
			this.setTranDate(SFALLDate.parse(new String(dest)));
		} catch (ParseException e) {
		}
		srcPos += 14;
		// 6 应答码
		dest = new byte[6];
		System.arraycopy(src, srcPos, dest, 0, dest.length);
		this.setRspCode(new String(dest).trim());
		srcPos += 6;
		// 7 应答码描述
		dest = new byte[42];
		System.arraycopy(src, srcPos, dest, 0, dest.length);
		this.setRspMsg(new String(dest,charset).trim());
		srcPos += 42;
		// 8 后续包标志
		dest = new byte[1];
		System.arraycopy(src, srcPos, dest, 0, dest.length);
		this.setConFla(new Integer(new String(dest).trim()));
		srcPos += 1;
		// 9 报文体长度
		dest = new byte[8];
		System.arraycopy(src, srcPos, dest, 0, dest.length);
		this.setLength(new Integer(new String(dest).trim()).intValue());
		srcPos += 8;

		// 10 操作员号
		dest = new byte[5];
		System.arraycopy(src, srcPos, dest, 0, dest.length);
		this.setCounterId(new String(dest).trim());
		srcPos += 5;
		// 11 请求方系统流水号
		dest = new byte[20];
		System.arraycopy(src, srcPos, dest, 0, dest.length);
		this.setThirdLogNo(new String(dest).trim());
		srcPos += 20;
		// 12 交易网代码
		dest = new byte[4];
		System.arraycopy(src, srcPos, dest, 0, dest.length);
		this.setQydm(new String(dest).trim());

	}

}
